import { parseMD5, sliceFileWithMd5 } from '@/Utils/uploadTools';
import { useState } from 'react';
import ProgressBars from '@/components/ChunkUpload/progresses';
import Axios from '@/Utils/axios';

// @ts-ignore
const requestAction = async (
  { file, md5, fileInfo, parentMd5 },
  { setProgresses },
) => {
  console.log('fileInfo', fileInfo);
  const formData = new FormData();
  formData.append('fileUpload', file);
  formData.append('fileInfo', JSON.stringify(fileInfo));
  formData.append('md5', md5);
  formData.append('parentMd5', parentMd5);
  return Axios.post('/api/upload', formData, {
    onUploadProgress: (ev) => {
      const p = ((ev.loaded / ev.total) * 100) | 0;
      setProgresses((old: any) => {
        return { ...old, [md5]: p };
      });
    },
  });
};

const ChunkUpload = ({ sliceSize = 1024 * 1024, concurrency = 5 }) => {
  const [s, setS] = useState('状态');
  const [progresses, setProgresses] = useState({});
  const [files, setFiles] = useState({});
  //当前文件是哪个 用hash指代
  const [cfh, setCFH] = useState('');

  const change = async (file: any) => {
    const currentFile = file.target.files[0];
    if (!currentFile) return;

    //初始化一次
    setProgresses({});
    setFiles({});
    setCFH('');
    setS('');

    setS('正在准备上传');

    //保存文件的详细信息
    const { name, size, type } = currentFile;
    const fileHash = await parseMD5(currentFile);
    // @ts-ignore
    setCFH(fileHash);

    const fileArr = await sliceFileWithMd5(currentFile, sliceSize);

    const filePush = fileArr.map((e) => ({ ...e, parentMd5: fileHash }));

    //  原文件的列表 用文件hash作为key，值是 切分文件的hash 和 文件信息
    const cFiles = {
      ...files,
      // @ts-ignore
      [fileHash]: {
        sliceHash: fileArr.map((e) => e.md5),
        fileInfo: {
          name,
          size,
          type,
        },
      },
    };
    setFiles(cFiles);

    setS('准备完成，开始上传');
    //根据文件切片，发出Promise.all
    // @ts-ignore
    handleRequest(concurrency, filePush, () => {
      setS('上传成功');
    });
  };

  const handleRequest = (len: number, source = [], callback: any) => {
    let doneNumber = 0;
    const total = source.length;
    const handler = () => {
      if (source.length > 0) {
        const s = source.shift();
        // @ts-ignore
        requestAction(s, { setProgresses })
          .then(() => {
            doneNumber++;
            handler();
          })
          .catch((err) => {
            throw Error(err);
          });
      }
      if (doneNumber >= total) {
        callback();
      }
    };
    for (let i = 0; i < len; i++) {
      handler();
    }
  };

  return (
    <>
      <div>{s}</div>
      <input type="file" onChange={change} />
      <br />
      {/*                                  hash指代的当前文件 */}
      {/*@ts-ignore*/}
      <ProgressBars data={progresses} files={files[cfh]} />
      {/*<FileTable />*/}
    </>
  );
};

export default ChunkUpload;
